package com.heatup.apt.api.service.impl;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.ImmutableMap;
import com.heatup.apt.api.service.DataDictService;
import com.heatup.apt.api.service.MealService;
import com.heatup.apt.api.service.OrderService;
import com.heatup.apt.api.service.UserMealCouponService;
import com.heatup.apt.api.service.UserService;
import com.heatup.apt.api.service.WeChatPayService;
import com.heatup.apt.common.constants.OrderContants;
import com.heatup.apt.common.dao.OrderDetailMapper;
import com.heatup.apt.common.dao.ServicePriceMapper;
import com.heatup.apt.common.dao.user.UserAccountConsumeMapper;
import com.heatup.apt.common.exception.OrderException;
import com.heatup.apt.common.util.DateUtil;
import com.heatup.apt.common.util.OrderUtil;
import com.heatup.apt.common.util.RequestTools;
import com.heatup.apt.common.util.StringUtil;
import com.heatup.apt.model.DataDict;
import com.heatup.apt.model.api.ApiResultModel;
import com.heatup.apt.model.order.OrderDetail;
import com.heatup.apt.model.order.OrderInfo;
import com.heatup.apt.model.user.UserAccountConsume;
import com.heatup.apt.model.user.UserInfo;
import com.heatup.apt.model.user.UserMealCoupon;

@Service
public class MealServiceImpl implements MealService {

	@Resource
	private OrderService orderService;
	
	@Resource
	private UserMealCouponService userMealCouponService;
	
	@Resource
	private DataDictService dataDictService;
	
	@Resource
	private OrderDetailMapper orderDetailMapper;
	
	@Resource
	private ServicePriceMapper servicePriceMapper;
	
	@Resource
	private UserService userService;
	
	
	@Resource
	private WeChatPayService weChatPayService;
	
	@Resource
	private UserAccountConsumeMapper userAccountConsumeMapper;
	/**
	 * 
	 * @param request
	 * @param apiResultModel
	 * @return
	 * @throws OrderException 
	 */
	@Transactional(rollbackFor = { Throwable.class })
	public ApiResultModel<Object> dealOrder(HttpServletRequest request, ApiResultModel<Object> apiResultModel, UserInfo userInfo) throws OrderException {
		String payAmount = RequestTools.RequestString(request, "payAmount", "");//支付总额 如果是配送 需要传10
		String orderType = RequestTools.RequestString(request, "orderType", "12");//orderType只能传12
//		String serviceId = RequestTools.RequestString(request, "serviceId", "");//null
		Integer mealCount = RequestTools.RequestInt(request, "mealCount", 1);//mealCount  买餐数量
		Integer storeId = RequestTools.RequestInt(request, "storeId", 0);//到店吃  需要传
		Integer payType =  RequestTools.RequestInt(request, "payType", 0);// 2 表示个人储值账户   只能传2
		String weixinAmt = RequestTools.RequestString(request, "weixinAmt", "");// 表示微信支付金额  
		String consumeAmt = RequestTools.RequestString(request, "consumeAmt", "");// 表示储值卡支付金额
		Integer sendType = RequestTools.RequestInt(request, "sendType", 0);// 2配送吃  1还是到店吃
		Integer userAddrId = RequestTools.RequestInt(request, "userAddrId", 0);// 配送地址id
		Integer eatTimeType =  RequestTools.RequestInt(request, "eatTimeType", 0); //吃饭时间类型
		
		String errMsg = null;
		if(StringUtils.isEmpty(payAmount) || (new BigDecimal(payAmount)).compareTo(BigDecimal.ZERO) == 0){
        	payAmount = "0";
        }
		if(StringUtils.isEmpty(weixinAmt) || (new BigDecimal(weixinAmt)).compareTo(BigDecimal.ZERO) == 0){
			weixinAmt = "0";
        }
		if(StringUtils.isEmpty(consumeAmt) || (new BigDecimal(consumeAmt)).compareTo(BigDecimal.ZERO) == 0){
			consumeAmt = "0";
        }
//		getTime
		if(eatTimeType > 3 || eatTimeType < 1) {
			errMsg = "请选择就餐类型";
		}
		Map<String, String> mapTime = getTime(eatTimeType);
		String startTime = mapTime.get("startTime");//就餐开始时间  
		String endTime = mapTime.get("endTime");//就餐结束时间
		
//		if(!dataValid(startTime)) errMsg = "请输入正确的时间！";
		Double payAmountTem = Double.parseDouble(payAmount);
		if(sendType == 1 && storeId == 0)  errMsg = "请选择门店！";
		if(sendType == 0)  errMsg = "请选择配送方式！";
		List<DataDict> dataDictList = dataDictService.queryDataDicts("SEND_MEAL_FEE");
		Double sendFee = (double) (dataDictList != null && dataDictList.size() > 0 ? dataDictList.get(0).getDictDisplayOrder() : 10);
		if(StringUtils.isBlank(startTime) || StringUtils.isBlank(endTime))  errMsg = "时间错误";
		if(payType != 2)  errMsg = "支付方式错误";
		if(sendType == 2 && Double.parseDouble(payAmount) != sendFee)  errMsg = "配送费不正确"; // 如果配送方式为快递
		
		if(sendType == 2 && Double.parseDouble(payAmount) != Double.parseDouble(consumeAmt)) errMsg = "代金卡金额错误"; 
			
		if(sendType == 2 && userAddrId == 0) errMsg = "请选择配送地址";
		if(mealCount < 1) errMsg = "至少消费一张餐券";
		UserMealCoupon umc = this.getMealCount(userInfo.getId());
		if(mealCount > umc.getMealCount()) errMsg = "没有足够的餐券";
		if(errMsg != null){
			apiResultModel.setRet(ApiResultModel.RET_ERROR);
			apiResultModel.setMsg(errMsg);
			return apiResultModel;
		}
		Integer serviceId = this.servicePriceMapper.queryServicePriceByServiceType(12);//餐的serviceId
		String tradeNo = OrderUtil.getOrderNumber(OrderContants.ORDER_SOURCE_WECHAT + "");// 创建订单流水
		// 添加支付方式
		if(sendType.intValue() == 2) {
			// 餐券+代金卡方式支付
			payType = OrderContants.PAY_TYPE_MEAL_COUPON_AND_PERSON_ACCOUNT;
		}else {
			// 餐券方式支付
			payType = OrderContants.PAY_TYPE_MEAL_COUPON;
		}
		//校验玩数据  插入数据  添加订单
		OrderInfo oi = new OrderInfo();
		oi.setOrderStatus(OrderContants.OrderStatus.NORMAL.getStatus());
        oi.setOrderSource(OrderContants.ORDER_SOURCE_WECHAT);
        oi.setOrderType(Integer.valueOf(orderType));
        oi.setOrderNumber(tradeNo);
        oi.setVersion(0);
        oi.setPayStatus(OrderContants.PayStatus.PAID);
        oi.setCreatedTime(new Date());
        oi.setUserId(userInfo.getId());
	    oi.setServiceId(serviceId);
        oi.setAmount(BigDecimal.valueOf(payAmountTem));
	    oi.setPayType(payType);
	    oi.setCancelAble("0");
	    oi.setPriceTypeCode("13"); //餐订单固定死   13   表示用券支付
        if(!StringUtil.isBlank(weixinAmt)){
        	oi.setWeixinAmt(new BigDecimal(weixinAmt));
        }
        if(!StringUtil.isBlank(consumeAmt)){
        	oi.setConsumeAmt(new BigDecimal(consumeAmt));
        }
        //添加订单详情
		boolean res = orderService.insert(oi);
		if(!res)
			throw new RuntimeException("创建订单失败");
		if(oi.getConsumeAmt().compareTo(BigDecimal.ZERO) > 0) {
//			//储值卡消费插入
//			this.weChatPayService.insertUserAccountConsume(userInfo, oi.getOrderNumber());
			 UserAccountConsume userAccountConsume = new UserAccountConsume();
		        userAccountConsume.setUserId(userInfo.getId());
		        userAccountConsume.setConsumeAmt(new BigDecimal(consumeAmt));
		        userAccountConsume.setConsumeType("1");
		        //修改消费类型，根据订单来消费
		        userAccountConsume.setRemark(OrderContants.OrderType.getOrderType(oi.getOrderType().toString()).getTitle());
		        userAccountConsume.setCreateTime(new Date());
		        userAccountConsume.setOrderId(oi.getId());
		        int bool = userAccountConsumeMapper.insertSelective(userAccountConsume);
		}
		OrderDetail orderDetail = new OrderDetail();
		orderDetail.setOrderId(Integer.valueOf(oi.getId()));
		orderDetail.setServiceId(oi.getServiceId());
		orderDetail.setStoreId(storeId);
		orderDetail.setSendType(sendType);
		orderDetail.setUserAddrId(userAddrId);
		orderDetail.setStartTime(DateUtil.parseUtilDate(startTime, 2));
		orderDetail.setEndTime(DateUtil.parseUtilDate(endTime, 2));
		orderDetail.setMealCount(mealCount);
		orderDetail.setEatTimeType(eatTimeType);
		final int orderDetailCount = orderDetailMapper.insert(orderDetail);
		//扣除餐券
		if (orderDetailCount < 1) {
			throw new OrderException("插入订单明细失败!");
		}
		umc.setMealCount(umc.getMealCount() - mealCount);
		boolean upMeal = userMealCouponService.updateById(umc);
		if (!upMeal) {
			throw new OrderException("跟新餐券失败");
		}
		//如果是送外卖   扣除配送费
		if(payType == 2 || payType == OrderContants.PAY_TYPE_MEAL_COUPON_AND_PERSON_ACCOUNT) {
			userInfo.setAccountAmt(userInfo.getAccountAmt().subtract(BigDecimal.valueOf(payAmountTem)));
			int upUserMoney = userService.updateUserInfo(userInfo);
			if (upUserMoney < 1) {
				throw new OrderException("更新餐券失败");
			}
		}
		
		apiResultModel.setData(oi);
		apiResultModel.setRet(ApiResultModel.RET_SUCCESS);
		apiResultModel.setMsg("下单成功");
		
		return apiResultModel;
	}
	
	/**
	 * 得到餐券总数
	 * @return
	 */
	public UserMealCoupon getMealCount(Integer userId) {
		UserMealCoupon umc = new UserMealCoupon();
		umc.setUserId(userId);
		umc = userMealCouponService.selectOne(umc);
		return umc;
	}
	
	public ImmutableMap<String, String> getTime(Integer eatMealType) {
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(new Date());
		calendar.add(Calendar.DAY_OF_MONTH, 1);//获取日
		String date = DateUtil.formatDate(calendar.getTime(), 1);
		String key = "";
		if(eatMealType == 1) {
			key = "meal_lunch_time";
		} else if(eatMealType == 2) {
			key = "meal_aftroon_time";
		} else if(eatMealType == 3) {
			key = "meal_denner_time";
		}
		String startDate = date;
		String endDate = date;
		List<DataDict> dataDictList = dataDictService.queryDataDicts(key);
		if(dataDictList != null && dataDictList.size() > 0) {
			String[] aRr = dataDictList.get(0).getDictName().split("|");
			startDate += " " + aRr[0];
			endDate += " " + aRr[1];
		} else {
			if(eatMealType == 1) {
				startDate = date + " 12:00:00";
				endDate = date + " 12:00:00";
			} else if(eatMealType == 2) {
				startDate = date + " 15:00:00";
				endDate = date + " 16:00:00";
			} else if(eatMealType == 3) {
				startDate = date + " 18:00:00";
				endDate = date + " 19:00:00";
			}
		}
		return ImmutableMap.of("startTime", startDate, "endTime", endDate);
	}
}
